<?php
// ----------------------------------------------------------------------------
// markItUp! BBCode Parser
// v 1.0.6
// Dual licensed under the MIT and GPL licenses.
// ----------------------------------------------------------------------------
// Copyright (C) 2009 Jay Salvat
// http://www.jaysalvat.com/
// http://markitup.jaysalvat.com/
// ----------------------------------------------------------------------------
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
// ----------------------------------------------------------------------------
// Thanks to Arialdo Martini, Mustafa Dindar for feedbacks.
// ----------------------------------------------------------------------------

define ("EMOTICONS_DIR", "/images/emoticons/");

function BBCode2Html ($str) {
	//$str = strip_tags($str);

	//Smileys to find...
	$in = array( 	 ':)',
					 ':D',
					 ':o',
					 ':P',
					 ':p',
					 ':(',
					 ';)'
					 );
					 // And replace them by...
					 $out = array(	 '<img alt=":)" class="emoticon" src="'.EMOTICONS_DIR.'face-smile.png" />',
					 '<img alt=":D" class="emoticon" src="'.EMOTICONS_DIR.'face-laugh.png"/>',
					 '<img alt=":o" class="emoticon" src="'.EMOTICONS_DIR.'face-surprised.png" />',
					 '<img alt=":p" class="emoticon" src="'.EMOTICONS_DIR.'face-raspberry.png" />',
					 '<img alt=":P" class="emoticon" src="'.EMOTICONS_DIR.'face-raspberry.png" />',
					 '<img alt=":(" class="emoticon" src="'.EMOTICONS_DIR.'face-sad.png" />',
					 '<img alt=";)" class="emoticon" src="'.EMOTICONS_DIR.'face-wink.png" />'
					 );
					 $str = str_replace($in, $out, $str);

					 $simple_search = array(
                '/\[b\](.*?)\[\/b\]/is',  
                '/\[i\](.*?)\[\/i\]/is',  
                '/\[u\](.*?)\[\/u\]/is',
    			'/\[url\=http:\/\/(.*?)\](.*?)\[\/url\]/is',  
                '/\[url\]http:\/\/(.*?)\[\/url\]/is',  
                '/\[url\=(.*?)\](.*?)\[\/url\]/is',  
                '/\[url\](.*?)\[\/url\]/is',    
                '/\[img\](.*?)\[\/img\]/is',  
                '/\[mail\=(.*?)\](.*?)\[\/mail\]/is',  
                '/\[mail\](.*?)\[\/mail\]/is',  
                '/\[size\=(.*?)\](.*?)\[\/size\]/is',  
                '/\[color\=(.*?)\](.*?)\[\/color\]/is',
					 //List
					 //'/\r\n\[list\=(.*?)\](.*?)\[\/list\]/ms',
					 //'/\r\n\[list\](.*?)\[\/list\]/ms',
					 //'/\r\n\[\*\]\s?(.*?)\n/ms',
    			'/\[list\=(.*?)\](.*?)\[\/list\]/ms',
				'/\[list\](.*?)\[\/list\]/ms',
				'/\r\n\[\*\]\s?(.*?)\r\n/ms',
    			'/\r\n\[\*\]\s?(.*?)/ms',
				'/\[\*\]\s?(.*?)\r\n/ms',
    			'/\[\*\]\s?(.*?)/ms',
					 //Quote
			    '/\[quote\](.*?)/is',
			    '/\[quote=(.*?)\](.*?)/is',
    			'/\[\/quote]/is',  
					 //added pre class for code presentation
              	'/\[code\](.*?)\[\/code\]/is'
              	);

              	$simple_replace = array(
                '<strong>$1</strong>',  
                '<em>$1</em>',  
                '<u>$1</u>',  
              	// added nofollow to prevent spam
                '<a href="http:\/\/$1" target="_blank" rel="nofollow" title="$2 - $1">$2</a>',  
                '<a href="http:\/\/$1" target="_blank" rel="nofollow" title="$1">$1</a>',
    			'<a href="http:\/\/$1" target="_blank" rel="nofollow" title="$2 - $1">$2</a>',  
                '<a href="http:\/\/$1" target="_blank" rel="nofollow" title="$1">$1</a>',
              	//added alt attribute for validation
                '<img src="$1" alt="" />',  
                '<a href="mailto:$1">$2</a>',  
                '<a href="mailto:$1">$1</a>',    
                '<span style="font-size: $1%;">$2</span>',  
                '<span style="color: $1;">$2</span>',
              	//List
    			'<ol style="display:block; margin:0px;" start="$1">$2</ol>',
				'<ul style="display:block; margin:0px;">$1</ul>',
				'<li>$1</li>',
    			'<li>$1</li>',
    			'<li>$1</li>',
    			'<li>$1</li>',
              	//Quote
              	//'<div class="quote" style="width:90%; margin:10px 0px 10px 20px; padding:5px 0px; background-color:#EEE0B4; border:1px solid #BEB084;">$1',
              	//'<div class="quote" style="width:90%; margin:10px 0px 10px 20px; padding:5px 0px; background-color:#EEE0B4; border:1px solid #BEB084;"><b><i>Geschreven door: $1</i></b><br />$2',
    			'<div class="quote">$1',
    			'<div class="quote"><b><i>Geschreven door: $1</i></b><br />$2',
    			'</div>',
              	//added pre class for code presentation
				'<pre class="code">$1</pre>'
				);

				// Do simple BBCode's
				$str = preg_replace ($simple_search, $simple_replace, $str);
				$str = closetags($str);
				// Do <blockquote> BBCode
				//$str = bbcode_quote ($str);
				//$str = str_replace('[/quote]', '</blockquote>', $str);
				//return preg_replace_callback('/\[quote(.*?)\]/msi','parse_quote', $str);
				$str = nl2br($str);
				 
				return $str;
}

function closetags ( $html )
{
	#put all opened tags into an array
	preg_match_all ( "#<([a-z]+)( .*)?(?!/)>#iU", $html, $result );
	$openedtags = $result[1];
	$openedtags = array_diff($openedtags, array("img", "hr", "br"));

	#put all closed tags into an array
	preg_match_all ( "#</([a-z]+)>#iU", $html, $result );
	$closedtags = $result[1];
	$len_opened = count ( $openedtags );
	# all tags are closed
	if( count ( $closedtags ) == $len_opened )
	{
		return $html;
	}
	$openedtags = array_reverse ( $openedtags );

	# close tags
	for( $i = 0; $i < $len_opened; $i++ )
	{
		if ( !in_array ( $openedtags[$i], $closedtags ) )
		{
			$html .= "</" . $openedtags[$i] . ">";
		}
		else
		{
			unset ( $closedtags[array_search ( $openedtags[$i], $closedtags)] );
		}
	}
	return $html;
}



function BBCode2Html_V1($text, $class=null) {
	$text = trim($text);

	// BBCode [code]
	if (!function_exists('escape')) {
		function escape($s) {
			global $text;
			$text = strip_tags($text);
			$code = $s[1];
			$code = htmlspecialchars($code);
			$code = str_replace("[", "&#91;", $code);
			$code = str_replace("]", "&#93;", $code);
			return '<pre><code>'.$code.'</code></pre>';
		}
	}
	$text = preg_replace_callback('/\[code\](.*?)\[\/code\]/ms', "escape", $text);

	// Smileys to find...
	$in = array( 	 ':)',
					 ':D',
					 ':o',
					 ':p',
					 ':(',
					 ';)'
					 );
					 // And replace them by...
					 $out = array(	 '<img alt=":)" src="'.EMOTICONS_DIR.'emoticon-smile.png" />',
					 '<img alt=":D" src="'.EMOTICONS_DIR.'emoticon-happy.png" />',
					 '<img alt=":o" src="'.EMOTICONS_DIR.'emoticon-surprised.png" />',
					 '<img alt=":p" src="'.EMOTICONS_DIR.'emoticon-tongue.png" />',
					 '<img alt=":(" src="'.EMOTICONS_DIR.'emoticon-unhappy.png" />',
					 '<img alt=";)" src="'.EMOTICONS_DIR.'emoticon-wink.png" />'
					 );
					 $text = str_replace($in, $out, $text);

					 // BBCode to find...
					 $in = array( 	 '/\[b\](.*?)\[\/b\]/ms',
					 '/\[i\](.*?)\[\/i\]/ms',
					 '/\[u\](.*?)\[\/u\]/ms',
					 '/\[img\](.*?)\[\/img\]/ms',
					 '/\[email\](.*?)\[\/email\]/ms',
					 '/\[url\="?(.*?)"?\](.*?)\[\/url\]/ms',
					 '/\[size\="?(.*?)"?\](.*?)\[\/size\]/ms',
					 '/\[color\="?(.*?)"?\](.*?)\[\/color\]/ms',
					 '/\[quote](.*?)\[\/quote\]/ms',
					 '/\[list\=(.*?)\](.*?)\[\/list\]/ms',
					 '/\[list\](.*?)\[\/list\]/ms',
					 '/\[\*\]\s?(.*?)\n/ms'
					 );
					 // And replace them by...
					 if(isset($class)) {
					 	$out = array(	 '<strong>\1</strong>',
						 '<em>\1</em>',
						 '<u>\1</u>',
						 '<img src="\1" alt="\1" />',
						 '<a href="mailto:\1">\1</a>',
						 '<a target="_blank" href="\1">\2</a>',
						 '<span style="font-size:\1%">\2</span>',
						 '<span style="color:\1">\2</span>',
						 '<span class="'.$class.'" style="background-color:white;">\1</span>',
						 '<ol start="\1">\2</ol><p class="'.$class.'">&nbsp;',
						 '<ul>\1</ul><p class="'.$class.'">&nbsp;',
						 '<li><p class="'.$class.'">\1</p></li>');
					 }else {
					 	$out = array(	 '<strong>\1</strong>',
						 '<em>\1</em>',
						 '<u>\1</u>',
						 '<img src="\1" alt="\1" />',
						 '<a href="mailto:\1">\1</a>',
						 '<a target="_blank" href="\1">\2</a>',
						 '<span style="font-size:\1%">\2</span>',
						 '<span style="color:\1">\2</span>',
						 '<span style="background-color:white;">\1</span>',
						 '<ol start="\1">\2</ol><p>&nbsp;',
						 '<ul>\1</ul><p>&nbsp;',
						 '<li><p>\1</p></li>');
					 }
					 $text = preg_replace($in, $out, $text);

					 // paragraphs
					 if(isset($class)) {
					 	$text = "<p class='".$class.">".preg_replace("/(\n){2,}/", "</p><br /><p class='".$class."'>&nbsp;", $text)."</p>";
					 }else {
					 	$text = "<p>".preg_replace("/(\n){2,}/", "</p><br /><p>&nbsp;", $text)."</p>";
					 }
					 $text = nl2br($text);

					 // clean some tags to remain strict
					 // not very elegant, but it works. No time to do better ;)
					 if (!function_exists('removeBr')) {
					 	function removeBr($s) {
					 		return str_replace("<br />", "", $s[0]);
					 	}
					 }
					 $text = preg_replace_callback('/<pre>(.*?)<\/pre>/ms', "removeBr", $text);
					 $text = preg_replace('/<p'.(isset($class) ? ' class="'.$class.'"' : '').'><pre>(.*?)<\/pre><\/p>/ms', "<pre>\\1</pre>", $text);

					 $text = preg_replace_callback('/<ul>(.*?)<\/ul>/ms', "removeBr", $text);
					 $text = preg_replace('/<p'.(isset($class) ? ' class="'.$class.'"' : '').'><ul>(.*?)<\/ul><\/p>/ms', "<ul>\\1</ul>", $text);

					 return $text;
}
?>